package partitions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PartitionDecorator {

	int numCoalitions;
	public int getNumCoalitions() {
		return numCoalitions;
	}


	public int getNumAgents() {
		return numAgents;
	}


	public Map<Integer, List<Integer>> getCoalitions() {
		return Collections.unmodifiableMap(coalitions);
	}

	int numAgents;
	Map<Integer, List<Integer>> coalitions;
	
	public PartitionDecorator(int[] partition){
		HashMap<Integer, List<Integer>> modifiableMap = new HashMap<Integer, List<Integer>>();
		HashMap<Integer, List<Integer>> unmodifiableMap = new HashMap<Integer, List<Integer>>();
		for(int i = 0; i < partition.length; i++){
			if(modifiableMap.get(i) == null)
				modifiableMap.put(i, new ArrayList<Integer>());
		}
		for(int i : modifiableMap.keySet())
			unmodifiableMap.put(i, Collections.unmodifiableList(modifiableMap.get(i)));
		coalitions = unmodifiableMap;
	}
	
	
	public static void main(String[] args) {
		int[] partition = new int[]{ 2, 3, 4, 2, 2, 3, 0, 3, 2, 5, 67, 2 , 3};
		int[] reduced = reduceIndices(partition);
		System.out.println("before: " + utils.Util.printIntArray(partition));
		System.out.println("after : " + utils.Util.printIntArray(reduced));
	}
	
	public static int[] reduceIndices(int[] partition){
		int[] result = new int[partition.length];
		int[] newToOldIndices = new int[partition.length];
		for(int i = 0; i < partition.length; i++){
			newToOldIndices[i] = -1;
		}
		int currentLargestIndex = -1;
		for(int i = 0; i < partition.length; i++){
			int index = 0;
			for(; index < partition.length; index++){
				if(newToOldIndices[index] == partition[i])
					break;
			}
			if(index == partition.length){
				currentLargestIndex++;
				newToOldIndices[currentLargestIndex] = partition[i];
				index = currentLargestIndex;
			}
			result[i] = index;
		}
		return result;
	}
	
	public static List<int[]> getCoalitionLists(int[] partition){
		List<int[]> coalitions = new ArrayList<int[]>();
		List<List<Integer>> coalitionLists = new ArrayList<List<Integer>>();
		for(int i = 0; i < partition.length; i++){
			if(partition[i] > coalitionLists.size() - 1)
				coalitionLists.add(new ArrayList<Integer>());
			List<Integer> coalition = coalitionLists.get(partition[i]);
			coalition.add(i);
		}
		for(int i = 0; i < coalitionLists.size(); i++){
			List<Integer> coalition = coalitionLists.get(i);
			int coalitionSize = coalition.size();
			int[] coalitionArray = new int[coalitionSize];
			for(int j = 0; j < coalitionSize; j++)
				coalitionArray[j] = coalition.get(j);
			coalitions.add(coalitionArray);
		}
		
		return coalitions;
	}	
	
	public static int[] convertFromListForm(List<List<Integer>> partition, int numAgents){
		int[] result = new int[numAgents];
		int counter = 0;
		for(List<Integer> coalition : partition){
			for(int agent : coalition){
				result[agent] = counter;
			}
			counter++;
		}
		return result;
	}
	
	public static String convertToHashString(int[] partition){
		StringBuffer result = new StringBuffer();
		for(int i = 0; i < partition.length - 1; i++){
			result.append(partition[i] + ",");
		}
		if(partition.length > 0){
			result.append(partition[partition.length - 1]);
		}
		return result.toString();
	}
	
	public static int getNumCoalitions(int[] partition){
		int maxSeen = -1;
		for(int i = 0; i < partition.length; i++){
			if(partition[i] > maxSeen)
				maxSeen = partition[i];
		}
		return maxSeen + 1;
	}
	
}
